package com.happy.code.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import org.apache.commons.lang3.StringUtils;

import com.happy.code.bean.ConfigVo;
import com.happy.code.bean.FieldInfo;
import com.happy.code.bean.TableInfo;
import com.happy.code.bean.TreeVo;
import com.happy.code.conf.ConfigLoader;
import com.happy.code.gui.event.ProgressEvent;
import com.happy.code.gui.event.ProgressEvent.EventType;
import com.happy.code.gui.event.ProgressEventListener;
import com.happy.code.util.DBHelper;
import com.happy.code.util.GeneraterWithMonitor;

import freemarker.template.TemplateException;
import net.miginfocom.swing.MigLayout;

/**
 * @类说明：
 * 
 * @author YANGJIE
 * @version 1.0
 * @创建时间：2016年8月6日 下午4:19:57
 */
public class MainPanel extends JPanel {

	private static final long serialVersionUID = -7453493229989547403L;

	private JScrollPane scrollPane;
	private JTree tree;
	private DefaultMutableTreeNode dbNode; // JTree根节点
	private DBHelper dbHelper = DBHelper.getInstance();
	private JPanel centerPanel;
	private JButton mergeButton;
	private JButton allButton;
	private JToolBar toolBar;
	private JLabel modelName;
	private JTextField modelNameTextField;
	private JLabel modelComments;
	private JTextField modelCommentsTextField;
	private JPanel statusPanel;
	private JComboBox<ConfigVo> comboBox;
	private ConfigLoader config = ConfigLoader.getInstance();
	private DefaultComboBoxModel<ConfigVo> dcbm = null;
	private JProgressBar progressBar;
	private JLabel infoLabel;

	public MainPanel() {

		initGUI();
	}

	private void initGUI() {
		setLayout(new BorderLayout(0, 0));

		scrollPane = new JScrollPane();
		add(scrollPane, BorderLayout.WEST);
		
		dbNode = new DefaultMutableTreeNode(new TreeVo(config.getCurr().getConfig().getDatabaseName()));

		tree = new JTree(dbNode);
		scrollPane.setViewportView(tree);
		scrollPane.setPreferredSize(new Dimension(250, 800));

		// 添加选择事件
//		tree.addTreeSelectionListener(new JTreeSelectionListener());
		tree.setCellRenderer(new TooltipTreeRenderer());
		ToolTipManager.sharedInstance().registerComponent(tree);

		centerPanel = new JPanel();
		centerPanel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "\u9009\u9879", TitledBorder.LEFT, TitledBorder.TOP, null, Color.GRAY));
		add(centerPanel, BorderLayout.CENTER);
		centerPanel.setLayout(new MigLayout("", "[][grow]", "[][]"));
		
		modelName = new JLabel("模块名称");
		modelName.setForeground(Color.RED);
		centerPanel.add(modelName, "cell 0 0,alignx trailing");
		
		modelNameTextField = new JTextField();
		centerPanel.add(modelNameTextField, "cell 1 0,growx");
		modelNameTextField.setColumns(10);
		
		modelComments = new JLabel("模块注释");
		modelComments.setForeground(Color.RED);
		centerPanel.add(modelComments, "cell 0 1,alignx trailing");
		
		modelCommentsTextField = new JTextField();
		centerPanel.add(modelCommentsTextField, "cell 1 1,growx");
		modelCommentsTextField.setColumns(10);
		
		toolBar = new JToolBar();
		add(toolBar, BorderLayout.NORTH);
		
		mergeButton = new JButton("合并生成");
		toolBar.add(mergeButton);
		
		allButton = new JButton("单独生成");
		toolBar.add(allButton);

		comboBox = new JComboBox<ConfigVo>(initCombox());
		comboBox.addItemListener(new ConfigComboBoxItem());
		comboBox.setPreferredSize(new Dimension(100, 30));
		toolBar.add(comboBox);
		allButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				List<TableInfo> tableInfos = getAllTable(dbNode);
				if (tableInfos.size()>0) {
					try {
						progressBar.setValue(0);
						infoLabel.setText("");
//						Generater.createFile(config.getCurr().getConfig(), tableInfos);
						progressBar.setMaximum(tableInfos.size());
						GeneraterWithMonitor gwm = new GeneraterWithMonitor();
						gwm.addProgressEventListener(pel);
						gwm.createFile(config.getCurr().getConfig(), tableInfos);
					} catch (IOException | TemplateException e1) {
						e1.printStackTrace();
					}
				}
			}
		});
		mergeButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				List<TableInfo> tableInfos = getSelectTable();
				if (tableInfos.size()>0) {
					String beanName = modelNameTextField.getText();
					String comments = modelCommentsTextField.getText();
					if (beanName == null) {
						beanName = "Default";
					}
					if (comments==null) {
						comments = "Default";
					}
					try {
						progressBar.setValue(0);
						infoLabel.setText("");
//						Generater.createMultiFile(config.getCurr().getConfig(), tableInfos, beanName, comments);
						progressBar.setMaximum(5);
						GeneraterWithMonitor gwm = new GeneraterWithMonitor();
						gwm.addProgressEventListener(pel);
						gwm.createMultiFile(config.getCurr().getConfig(), tableInfos, beanName, comments);
					} catch (IOException | TemplateException e1) {
						e1.printStackTrace();
					}
				}
			}
		});

		
		statusPanel = new JPanel();
		FlowLayout flowLayout = (FlowLayout) statusPanel.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);
		add(statusPanel, BorderLayout.SOUTH);
		
		progressBar = new JProgressBar();
		statusPanel.add(progressBar);
		
		infoLabel = new JLabel("");
		statusPanel.add(infoLabel);

		new Thread(new LoadColumnThread()).start();
	}
	
	public ProgressEventListener pel = new ProgressEventListener() {
		@Override
		public void onProgressEvent(ProgressEvent event) {
			if (event.getType() == EventType.normal) {
				progressBar.setValue(event.getCurr());
				infoLabel.setText((int) (progressBar.getPercentComplete() * 100) + "%" + " " + event.getInfo());
			} else if (event.getType() == EventType.end) {
				progressBar.setValue(progressBar.getMaximum());
				infoLabel.setText("100%" + " " + event.getInfo());
			}
		}
	};

	/**
	 * combox选择事件
	 */
	private class ConfigComboBoxItem implements ItemListener {
		public void itemStateChanged(ItemEvent e) {
			if (e.getStateChange()==ItemEvent.SELECTED) {				
				ConfigVo configVo = (ConfigVo) dcbm.getSelectedItem();
				config.setCurr(configVo);
				// 刷新tree读取数据库
				dbNode.removeAllChildren();
				dbNode.setUserObject(new TreeVo(config.getCurr().getConfig().getDatabaseName()));
				tree.updateUI();
				new Thread(new LoadColumnThread()).start();
			}
		}
	}
	
	/*class JTreeSelectionListener implements TreeSelectionListener {
		@SuppressWarnings("unused")
		public void valueChanged(TreeSelectionEvent e) {
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
			if (node == null)
				return;
			int count = node.getChildCount();
			//int level = node.getLevel();
			Object object = node.getUserObject();
			if (object != null) { // node.isLeaf() //node.isRoot()
				TreeVo treeVo = (TreeVo) object;
				String name = treeVo.getName();
				int level = node.getLevel();
				if (level == 0) { // 数据库层
//					System.out.println("数据库 "+name);
					if (count == 0) {
						// 初始化数据库
					}
				} else if (level == 1) { // 表层
//					System.out.println("表 "+name);
					int selnum = tree.getSelectionCount();
					if (count == 0) {
						// 初始化表字段
					}
				} else if (level == 2) { // 字段层
//					System.out.println("字段 "+name);
					int selnum = tree.getSelectionCount();
					DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
					// 找到父层做处理
				}
			}
		}
	}*/
	
	private DefaultComboBoxModel<ConfigVo> initCombox() {
		List<ConfigVo> list = config.getConfigVos();
		Vector<ConfigVo> v = new Vector<ConfigVo>();
		v.addAll(list);
		dcbm = new DefaultComboBoxModel<ConfigVo>(v);
		return dcbm;
	}
	
	/**
     * 需要生成代码的表
     *
     * @param conf
     * @return
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    private List<TableInfo> getTableInfos() throws ClassNotFoundException, SQLException {
//        Connection connection = DbUtils.getInstance().getConnection();
//        DatabaseMetaData metaData = DbUtils.getInstance().getMetaData(connection);
//        List<String> tableNames = Arrays.asList(conf.getTables().split(","));
//        return DbUtils.getInstance().getAllTables(metaData, tableNames);
    	return dbHelper.getAllTablesWithColumns();
    }
    
    /**
     * 单独开线程处理数据
     * @author YJ
     */
    class LoadColumnThread implements Runnable {

		public void run() {			
			List<TableInfo> tableInfos = null;
			try {
				tableInfos = getTableInfos();
			} catch (ClassNotFoundException | SQLException e) {
				e.printStackTrace();
				return;
			}
			DefaultMutableTreeNode tableNode = null;
			for (TableInfo tableInfo : tableInfos) {
				tableNode = new DefaultMutableTreeNode(new TreeVo(tableInfo.getTableName(), tableInfo));
				if (tableInfo.getFieldInfos()!=null) {
					List<FieldInfo> fieldInfos = tableInfo.getFieldInfos();
					for (FieldInfo fieldInfo : fieldInfos) {
						DefaultMutableTreeNode node = new DefaultMutableTreeNode(new TreeVo(fieldInfo.getColumnName()+" - "+fieldInfo.getColumnType()));
						tableNode.add(node); // 添加表字段
					}
				}
				
				dbNode.add(tableNode); // 添加表
			}
			TreeModel treeModel = new DefaultTreeModel(dbNode);
			tree.setModel(treeModel);
			tree.expandPath(new TreePath(dbNode));
			JScrollBar sBar = scrollPane.getVerticalScrollBar(); // 得到JScrollPane中的JScrollBar
			sBar.setValue(sBar.getMaximum()); // 设置JScrollBar的位置到最后
			sBar.setValue(sBar.getMinimum()); // 设置JScrollBar的位置到最前
		}

	}
    
	@SuppressWarnings("serial")
	class TooltipTreeRenderer extends DefaultTreeCellRenderer {
		@Override
		public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,
				boolean leaf, int row, boolean hasFocus) {
			final Component rc = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
			TreeVo treeVo = (TreeVo)node.getUserObject();
			TableInfo tableInfo = treeVo.getTableInfo();
			String tooltip = String.valueOf(value);
			if (tableInfo!=null && StringUtils.isNotBlank(tableInfo.getTableDesc())) {				
				tooltip = tableInfo.getTableDesc();
			}
			this.setToolTipText(tooltip);
			return rc;
		}
	}
	
	/**
	 * 获取所有表
	 * @param node
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<TableInfo> getAllTable(DefaultMutableTreeNode node) {
		List<TableInfo> tableInfoList = new ArrayList<TableInfo>();
		Enumeration<DefaultMutableTreeNode> children = node.children();
		
		while (children.hasMoreElements()) {
			DefaultMutableTreeNode child = children.nextElement();
			if (!child.isLeaf()) { // 是否叶子节点
				if (child.getLevel() == 1) { // 表
					TreeVo treeVo = (TreeVo) child.getUserObject();
					if (treeVo != null) {
						tableInfoList.add(treeVo.getTableInfo());
					}
				}
			}
		}
		return tableInfoList;
	}
	
	/**
	 * 获取选中的表
	 * @return
	 */
	public List<TableInfo> getSelectTable() {
		TreePath[] treePaths = tree.getSelectionPaths();
		if (treePaths==null) {
			return new ArrayList<TableInfo>();
		}
		List<TableInfo> tableInfos = new ArrayList<TableInfo>();
		for (int i = 0; i < treePaths.length; i++) {
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePaths[i].getLastPathComponent();
			if (!node.isLeaf()) { // 是否叶子节点
				if (node.getLevel() == 1) { // 表
					TreeVo treeVo = (TreeVo) node.getUserObject();
					if (treeVo != null) {
						tableInfos.add(treeVo.getTableInfo());
					}
				}
			}
		}
		
		return tableInfos;
	}
}
